package com.ssy.lingxi.platform.manage.serviceimpl;

import cn.hutool.core.util.StrUtil;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.platform.manage.entity.base.AppVersionManager;
import com.ssy.lingxi.platform.manage.model.request.appversion.AppVersionAddReq;
import com.ssy.lingxi.platform.manage.model.request.appversion.AppVersionPageReq;
import com.ssy.lingxi.platform.manage.model.request.appversion.AppVersionUpdateReq;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.response.AppVersionManagerRes;
import com.ssy.lingxi.platform.manage.model.response.NewVersionRes;
import com.ssy.lingxi.platform.manage.repository.AppVersionManagerRepository;
import com.ssy.lingxi.platform.manage.service.IAppVersionManagerService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @menu 平台后台-系统管理-APP版本管理实现类
 * @author wyx
 * @version 2.0.0
 * @date 2021-11-12
 */
@Service
public class AppVersionManagerServiceImpl implements IAppVersionManagerService {
    @Resource
    private AppVersionManagerRepository appVersionManagerRepository;


    /**
     * 新增版本
     * @param req 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> add(AppVersionAddReq req) {
        AppVersionManager appVersionManager = appVersionManagerRepository.findFirstByOrderByIdDesc();
        //版本号校验不能大于上个版本号
        if (appVersionManager != null) {
            if (compareToVersion(appVersionManager.getVersion(), req.getVersion())) {
                return Wrapper.fail(ResponseCode.CURRENT_VERSION_GT_LAST_VERSION);
            }
        }

        AppVersionManager appVersion = new AppVersionManager();
        appVersion.setVersion(req.getVersion());
        appVersion.setContent(req.getContent());
        appVersion.setType(req.getType());
        appVersion.setReleaseTime(DateTimeUtil.parseDateTime(req.getReleaseTime()));
        appVersion.setInstallPack(req.getInstallPack());

        appVersionManagerRepository.save(appVersion);
        return Wrapper.success();
    }

    /**
     * 修改版本
     * @param req 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> update(AppVersionUpdateReq req) {
        AppVersionManager appVersionManager = appVersionManagerRepository.findById(req.getId()).orElse(null);
        if (appVersionManager == null) {
            return Wrapper.fail(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        appVersionManager.setContent(req.getContent());
        appVersionManager.setType(req.getType());
        appVersionManager.setInstallPack(req.getInstallPack());
        appVersionManager.setReleaseTime(DateTimeUtil.parseDateTime(req.getReleaseTime()));
        appVersionManagerRepository.save(appVersionManager);
        return Wrapper.success();
    }

    /**
     * 查看版本
     * @param req 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<AppVersionManagerRes> find(CommonIdRequest req) {
        AppVersionManager appVersionManager = appVersionManagerRepository.findById(req.getId()).orElse(null);
        if (appVersionManager == null) {
            return Wrapper.fail(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(new AppVersionManagerRes(appVersionManager));
    }

    /**
     * 分页查看版本列表
     * @param req 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<AppVersionManagerRes>> page(AppVersionPageReq req) {
        Pageable page = PageRequest.of(req.getCurrent() - 1, req.getPageSize(), Sort.by("id").descending());
        Page<AppVersionManager> all = appVersionManagerRepository.findAll((root, query, builder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (StrUtil.isNotBlank(req.getStartDate())) {
                predicateList.add(builder.greaterThanOrEqualTo(root.get("releaseTime").as(LocalDateTime.class), LocalDateTime.parse(req.getStartDate().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }
            if (StrUtil.isNotBlank(req.getEndDate())) {
                predicateList.add(builder.lessThanOrEqualTo(root.get("releaseTime").as(LocalDateTime.class), LocalDateTime.parse(req.getEndDate().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }
            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }, page);
        return Wrapper.success(new PageData<>(all.getTotalElements(), all.getContent().stream().map(AppVersionManagerRes::new).collect(Collectors.toList())));
    }

    /**
     * APP端 - 查看最新版本号
     * @return 返回结果
     */
    @Override
    public Wrapper<NewVersionRes> findNewVersion() {
        AppVersionManager appVersionManager = appVersionManagerRepository.findFirstByOrderByIdDesc();
        if (appVersionManager == null) {
            return Wrapper.success();
        }
        return Wrapper.success(new NewVersionRes(appVersionManager.getId(), appVersionManager.getVersion(), appVersionManager.getType(), appVersionManager.getInstallPack()));
    }


    /**
     * 版本号校验不能大于上个版本号
     * @param oldVersion 旧版本
     * @param newVersion 新版本
     * @return 比较结果 旧版本大于大于新版本返回true，否则false
     */
    private boolean compareToVersion(String oldVersion, String newVersion) {
        if (oldVersion.equals(newVersion)) {
            return true;
        }
        String[] oldVersionArray = oldVersion.split("(V|\\.)");
        String[] newVersionArray = newVersion.split("(V|\\.)");
        //逐段比较版本号，先比较第一位
        int result = 0;
        for (int i = 1; i <= 3; i++) {
            long oldNum = Long.parseLong(oldVersionArray[i]);
            long newNum = Long.parseLong(newVersionArray[i]);
            result = Long.compare(oldNum, newNum);
            if (result != 0) {
                break;
            }
        }
        return result > 0;
    }
}
